package com.tencent.cloud.iov.util;

import android.content.Context;
import android.graphics.Bitmap;
import android.support.annotation.NonNull;
import android.text.TextUtils;

import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;

/**
 * @author saixiang
 * @date 2018/9/5
 */
public class FileUtils {

    private static Context sContext;

    private FileUtils() {

    }

    public static void init(@NonNull Context context) {
        sContext = context.getApplicationContext();
    }

    public static void storeStringData2File(String data, String fileName) throws IOException {
        if (sContext == null) {
            return;
        }
        String filePath = sContext.getFilesDir().getAbsolutePath() + fileName;
        File file = new File(filePath);
        if (!file.exists()) {
            boolean isSuccess = file.createNewFile();
            if (!isSuccess) {
                //没有文件读写权限
                return;
            }
        }
        DataOutputStream out = new DataOutputStream(new FileOutputStream(file));
        out.writeLong(System.currentTimeMillis());
        out.writeInt(data.length());
        out.writeBytes(data);
        out.close();

    }

    public static Result getStringDataFromFile(String fileName) {
        if (sContext == null) {
            return null;
        }
        String filePath = sContext.getFilesDir().getAbsolutePath() + fileName;
        File file = new File(filePath);
        if (!file.exists()) {
            return null;
        }
        try {
            DataInputStream in = new DataInputStream(new FileInputStream(file));
            Result result = new Result();
            result.time = in.readLong();
            int length = in.readInt();
            byte[] bytes = new byte[length];
            in.read(bytes);
            result.data = new String(bytes);
            return result;
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static void close(OutputStream outputStream) {
        if (outputStream != null) {
            try {
                outputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public static boolean saveBitmap(File file, Bitmap bitmap) {
        FileOutputStream fos = null;
        BufferedOutputStream bos = null;
        try {
            fos = new FileOutputStream(file);
            bos = new BufferedOutputStream(fos);
            bitmap.compress(Bitmap.CompressFormat.JPEG, 100, bos);
            bos.flush();
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        } finally {
            close(bos);
            close(fos);
        }
        return true;
    }

    public static void copyFile(File sourceFile, File targetFile) {
        FileInputStream input = null;
        FileOutputStream output = null;

        try {
            input = new FileInputStream(sourceFile);
            output = new FileOutputStream(targetFile);
            byte[] bt = new byte[1024];
            int realByte = 0;
            /**      input.read(bt)
             * Reads up to <code>b.length</code> bytes of data from this input
             * stream into an array of bytes. This method blocks until some input
             * is available.
             *
             * @param      b   the buffer into which the data is read.
             * @return the total number of bytes read into the buffer, or
             *             <code>-1</code> if there is no more data because the end of
             *             the file has been reached.
             * @exception IOException  if an I/O error occurs.
             */
            while ((realByte = input.read(bt)) > 0) {

                /**   output.write(bt,0,realbyte)
                 * Writes <code>len</code> bytes from the specified byte array
                 * starting at offset <code>off</code> to this file output stream.
                 *
                 * @param      b     the data.
                 * @param      off   the start offset in the data.
                 * @param      len   the number of bytes to write.
                 * @exception IOException  if an I/O error occurs.
                 */
                output.write(bt, 0, realByte);
            }

            output.close();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (input != null) {
                    input.close();
                }
                if (output != null) {
                    output.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }


    /**
     * 删除文件，可以是文件或文件夹
     *
     * @param fileName 要删除的文件名
     * @return 删除成功返回true，否则返回false
     */
    public static boolean deleteFileOrDirectory(String fileName) {
        if (TextUtils.isEmpty(fileName)) {
            return false;
        }
        File file = new File(fileName);
        if (!file.exists()) {
            return false;
        } else {
            if (file.isFile()) {
                return deleteFile(fileName);
            } else {
                return deleteDirectory(fileName);
            }
        }
    }

    /**
     * 删除单个文件
     *
     * @param fileName 要删除的文件的文件名
     * @return 单个文件删除成功返回true，否则返回false
     */
    public static boolean deleteFile(String fileName) {
        File file = new File(fileName);
        // 如果文件路径所对应的文件存在，并且是一个文件，则直接删除

        if (file.exists() && file.isFile()) {
            return file.delete();
        } else {
            return false;
        }
    }

    /**
     * 删除目录及目录下的文件
     *
     * @param dir 要删除的目录的文件路径
     * @return 目录删除成功返回true，否则返回false
     */
    public static boolean deleteDirectory(String dir) {
        //如果dir不以文件分隔符结尾，自动添加文件分隔符
        if (!dir.endsWith(File.separator)) {
            dir += File.separator;
        }
        File dirFile = new File(dir);
        //如果dir对应的文件不存在，或者不是一个目录，则退出
        if (!dirFile.exists() || !dirFile.isDirectory()) {
            return false;
        }
        boolean flag = true;
        // 删除文件夹中的所有文件包括子目录
        File[] files = dirFile.listFiles();
        for (int i = 0; i < files.length; i++) {
            //删除子文件
            if (files[i].isFile()) {
                flag = deleteFile(files[i].getAbsolutePath());
                if (!flag) {
                    break;
                }
            }            // 删除子目录
            else if (files[i].isDirectory()) {
                flag = deleteDirectory(files[i].getAbsolutePath());
                if (!flag) {
                    break;
                }
            }
        }
        if (!flag) {
            return false;
        }
        // 删除当前目录
        return dirFile.delete();
    }


    public static class Result {
        public long time;
        public String data;
    }
}
